package com.it.rpc.core.client;

import com.alibaba.fastjson.JSON;
import com.it.rpc.core.codec.RequestBody;
import com.it.rpc.core.codec.ResponseBody;
import com.it.rpc.core.protocol.Request;
import com.it.rpc.core.protocol.Response;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class RpcClientProxy implements InvocationHandler {
    /**
     * 获取动态代理的对象，
     *
     * @param clazz 接口的字节码
     * @param <T>
     * @return
     */
    public <T> T getProxyObj(Class<T> clazz) {
        T obj = (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, this);
        return obj;
    }

    /**
     * 代理方法 增强方法
     *
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//     1、    准备请求体的数据 也就是编码层 codec
        Request request = getRequest(method, args);
        System.out.println("远程过程调用");
        RpcClientTransport rpcClientTransport = new RpcClientTransport();
        Response response = rpcClientTransport.send(request);
        if (response != null) {
            if (response.getHeader().equals("version=1")) {
//                得到相应结果，并且返回
                ResponseBody responseBody = (ResponseBody) JSON.parseObject(response.getData(), ResponseBody.class);
                return JSON.parseObject(JSON.toJSONString(responseBody.getRetObject()),
                        method.getReturnType());
            }
        }
        return null;
    }

    private Request getRequest(Method method, Object[] args) throws IOException {
        String methodName = method.getName();
        String intefaceName = method.getDeclaringClass().getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
        RequestBody requestBody = new RequestBody();
        requestBody.setMethodName(methodName);
        requestBody.setInterfaceName(intefaceName);
        requestBody.setArgs(args);
        requestBody.setParameterTypes(parameterTypes);

        // JSON序列化对象
        byte[] requestBodyByte = JSON.toJSONBytes(requestBody);

//        2、 进行rpc层协议封装 protocol
        Request request = new Request();
        request.setHeader("version=1");
        request.setData(requestBodyByte);
        return request;
    }
}
